﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms.DataVisualization.Charting;
using MetingTempLichtVochtBeweging.ThingSpeak;
using Newtonsoft.Json;

namespace ThingSpeak
{
    public class ThinkSpeak
    {
        #region Declare

        private const string _url = "http://api.thingspeak.com/";
        private string _updateKey;
        private string _downloadKey;

        #endregion

        #region Initialize

        public ThinkSpeak(string updateKey, string downloadKey)
        {
            _updateKey = updateKey;
            _downloadKey = downloadKey;
        }

        #endregion

        #region Functions

        public bool UpdateThinkSpeakFeed(string[] fields, out int responseCode)
        {
            var sb = new StringBuilder();

            // Build the query-string
            sb.Append(_url + "update?key=" + _updateKey);

            // build the values
            for (int index = 0; index < fields.Length; index++)
            {
                var field = fields[index];
                sb.Append(UrlEncode(index + 1, field));
            }

            // bake the message to send
            var message = sb.ToString();

            // send it
            var response = PostToThingSpeak(message);

            // check the response
            responseCode = int.Parse(response);
            if (responseCode > 0)
            {
                return true;

            }
            return false;
        }

        public RootObject RetrieveThingSpeakFeedRoot(int channelId)
        {
            var postString = @"https://api.thingspeak.com/channels/" + channelId.ToString() + @"/feeds?";
            string response;
            response = this.PostToThingSpeak(postString);

            // find the beginning
            var jsonString = CleanTheResponse(response);

            var obj = JsonConvert.DeserializeObject<RootObject>(jsonString);
            return obj;
        }

        public List<DataPoint> ConvertToDataPoints(List<Feed> feed, int fieldNumber)
        {
            List<DataPoint> dataPoints = new List<DataPoint>();
            foreach (Feed dataEntry in feed)
            {
                var createdAtString = dataEntry.created_at;
                string value = string.Empty;
                switch (fieldNumber)
                {
                    case 1:
                        value = dataEntry.field1;
                        break;
                    case 2:
                        value = dataEntry.field2;
                        break;
                    case 3:
                        value = dataEntry.field3;
                        break;
                    case 4:
                        value = dataEntry.field4;
                        break;
                    case 5:
                        value = dataEntry.field5;
                        break;
                    case 6:
                        value = dataEntry.field6;
                        break;
                    case 7:
                        value = dataEntry.field7;
                        break;
                    case 8:
                        value = dataEntry.field8;
                        break;    
                }
                DateTime createdAtDate;
                DateTime.TryParse(createdAtString, out createdAtDate);

                if (string.IsNullOrEmpty(value) == false)
                {
                    var datapoint = new DataPoint(createdAtDate.ToOADate(), value);
                    //Debug.WriteLine(createdAtDate + " " + value);
                    dataPoints.Add(datapoint);
                }

                
            }
            dataPoints.Sort(DataPointSorter);

            return dataPoints;
        } 

        private string CleanTheResponse(string response)
        {
            var begin = "{\"channel\"";
            var firstIndex = response.IndexOf(begin);
            var newresponse = response.Substring(firstIndex);

            var end = "</div>";
            firstIndex = newresponse.IndexOf(end);
            newresponse = newresponse.Substring(0, firstIndex);

            return newresponse;
        }

        #endregion

        #region helpers
        private int DataPointSorter(DataPoint x, DataPoint y)
        {
            return x.XValue.CompareTo(y.XValue);
        }

        private string PostToThingSpeak(string post)
        {
            // Hit the URL with the query-string and put the response in webResponse
            HttpWebRequest myRequest = (HttpWebRequest) WebRequest.Create(post);

            try
            {
                HttpWebResponse webResponse = (HttpWebResponse)myRequest.GetResponse();
                Stream responseStream = webResponse.GetResponseStream();
                StreamReader readStream = new StreamReader(responseStream, Encoding.ASCII);
                var responseString = readStream.ReadToEnd();
                return responseString;
            }
            catch (WebException ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
                return "0";
            }
        }

        private string UrlEncode(int fieldNumber, string message)
        {
            var sb = new StringBuilder();
            sb.Append("&field");
            sb.Append(fieldNumber);
            sb.Append("=");
            sb.Append(message);
            return sb.ToString();
        }

        #endregion
    }
}
